home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib / panel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-22  |  19.2 KB  |  690 lines

  1. /*    PANEL . C    A library of Control Panel
  2. #
  3. %    Copyright (c)    Jin, Guojun
  4. %
  5. %    This file includes SLIDER, Multiple-Key BUTTON and Press BUTTON
  6. %    routines for creating, drawing, reading, setting, and controling
  7. %    their key or position. TextLine() is used for window input with
  8. %    a multiple-key button. It is better to keep it right side empty.
  9. %    When button or slider created, its valid=1;    If valid=0, it is
  10. %    not active at all.
  11. %    Use GetCloseColor() and GetGray() to set colors & grays from colormap.
  12. %    They must be set by other program after the color-map initialized.
  13. %
  14. %    Memory allocation:
  15. %        zalloc() will zero all cells but is slower than nzalloc().
  16. %
  17. % AUTHOR:    Jin Guojun - Lawrence Berkeley Laboratory    4/1/91
  18. */
  19.  
  20. #include "panel.h"
  21.  
  22. #ifndef    ButtonTColor
  23. #define    ButtonTColor    Green
  24. #endif
  25. #ifndef    PB_Fill
  26. #define    PB_Fill    lightGray
  27. #endif
  28.  
  29. int    PopLineHeight;
  30. PColor    Black, White, Visible, darkGray, lightGray, Gray,
  31.     Red, Green, Blue, Yellow,
  32.     black1, white1, gray1, HBGround=BGround;
  33. XColor    graylevel[MaxColors];    /* locally calculate or store(load) to VCT */
  34.  
  35.  
  36. /*=======================================================
  37. %    Following routines are to build panel & parts    %
  38. =======================================================*/
  39. Panel*
  40. CreatePanel(x, y, w, h, name, parent, WEMask)
  41. char    *name;
  42. WinAttribute    *parent;
  43. {
  44. register Panel    *p=zalloc(sizeof(*p), 1, name);
  45.  
  46. p->expose = PrtCAST &p->event;
  47. p->root = parent->root;
  48. p->dpy = parent->dpy;
  49. p->colormap = parent->cmap;
  50. p->name = str_save(name);
  51. p->x0 = x;    p->y0 = y;
  52. p->width = w;    p->height = h;
  53. p->icon_width = 0;    /* no icon    */
  54.  
  55. WEMask |= ButtonAction | KeyPressMask | PointerMotionMask;
  56. CreateWindow(p, parent, XCreateFontCursor(p->dpy, XC_top_left_arrow), WEMask,
  57.     True, 0);
  58. SetFontGetSize(p, "8x13bold");
  59. XSelectInput(p->dpy, p->win, WEMask | ExposureMask);
  60. return    p;
  61. }
  62.  
  63. Slider*
  64. CreateSlider(p, x, y, scale, v0, v1, numb, vert, name, info, bc, rc)
  65. Panel    *p;
  66. char    *name, *info;
  67. {
  68. register Slider    *s;
  69. register int    i, slen;
  70.  
  71. stry:    slen = (v1 - v0) / scale;
  72. if (vert && slen+y > p->height || !vert && slen+x > p->width)    {
  73.     scale++;    goto    stry;
  74.     }
  75. s = zalloc(sizeof(*s), 1, name);
  76. s->defscale = s->scale = scale;
  77. s->defmin = (s->min = v0) / scale;
  78. s->defmax = (s->max = v1) / scale;
  79. s->numb = numb;
  80. s->rl = slen;
  81. s->rw = RailWidth;
  82. s->rx = x;    s->ry = y;
  83. s->rcolor = rc;
  84. s->pan = p;
  85. s->sx = zalloc(numb, sizeof(*(s->sx)), "sx");
  86. s->sy = zalloc(numb, sizeof(*(s->sy)), "sy");
  87. s->vert = vert;
  88. if (vert){
  89.     s->sh = HandleWidth;
  90.     s->sw = HandleHeight;
  91.     s->sy[0] = y;
  92.     s->sx[0] = x - (s->sw-s->rw >> 1);
  93.     if (numb>1){
  94.         s->sy[1] = s->sy[0] + s->sh;
  95.         s->sx[1] = s->sx[0];
  96.     }
  97. }
  98. else    {    /*    horizontal    */
  99.     s->sw = HandleWidth;
  100.     s->sh = HandleHeight;
  101.     s->sx[0] = x;
  102.     s->sy[0] = y - (s->sh-s->rw >> 1);
  103.     if (numb>1){
  104.         s->sx[1] = s->sx[0] + s->sw;
  105.         s->sy[1] = s->sy[0];
  106.     }
  107. }
  108. s->name = str_save(name);
  109. s->namex = s->rx - strlen(s->name)*p->font_w - (TextLMargin>>1);
  110. i = strlen(info)+1;
  111. s->info = zalloc(i, 1, info);
  112. if (i>1){
  113.     strcpy(s->info, info);
  114.     s->infy = s->sy[0] - (HandleHeight >> 1) - TextVMargin;
  115. }
  116. else    s->infy = s->sy[0] - p->font_h;
  117. s->infx = s->rx + (slen - p->font_w * i >> 1) + (TextLMargin>>1);
  118. s->scolor = zalloc(numb, sizeof(*(s->scolor)), "scolor");
  119. for (i=numb--; i--;)
  120.     if (bc < 128)    /* bc is color entry    */
  121.     s->scolor[i] = bc + (numb-i << 4);
  122.     else
  123.     s->scolor[i] = bc - (numb-i << 3);
  124. s->tcolor = Green;
  125. #ifdef    _DEBUG_
  126. message("npos=%d, ipos=%d, rx=%d, rl=%d\n", s->namex, s->infx, s->rx, s->rl);
  127. #endif
  128. s->valid = True;
  129. return    s;
  130. }
  131.  
  132. Button*
  133. CreateButton(p, x, y, numb, name, bname, bc, pc)
  134. Panel    *p;
  135. char    *name, **bname;
  136. {
  137. register Button    *b;
  138. register int    i, w;
  139.  
  140. /*    4 is rough estimation for average words in each button    */
  141. if (x + p->font_w * 4 * numb > p->width || y+ButtonHeight > p->height)
  142.     prgmerr(numb, "Button  %s out of panel", name);
  143. b = zalloc(sizeof(*b), 1, name);
  144. b->name = str_save(name);
  145. b->namex = x - strlen(name)*p->font_w - 4;
  146. b->bname = zalloc(sizeof(*(b->bname)), numb, "bname");
  147. b->bw = zalloc(sizeof(*(b->bw)), numb, "bwidth");
  148. b->x = x;
  149. b->y = y;
  150. b->hei = ButtonHeight;
  151. b->numb = numb;
  152. for (i=w=0; i<numb; i++){
  153.     w += b->bw[i] = strlen(bname[i])*p->font_w + (TextLMargin<<1);;
  154.     b->bname[i] = zalloc(strlen(bname[i])+1, 1, bname[i]);
  155.     strcpy(b->bname[i], bname[i]);
  156. }
  157. b->rmb = w;
  158. b->color = zalloc(numb, sizeof(*(b->color)), "Bcolor");
  159. for (i=numb; i--;)
  160.     b->color[i] = bc;    /* button color */
  161. b->dimcolor = pc;        /* pressed color */
  162. b->tcolor = ButtonTColor;
  163. b->pan = p;
  164. b->valid = True;
  165. return    b;        /* bw & bname will be set by user    */
  166. }
  167.  
  168. PressButton*
  169. CreatePressButton(p, x, y, name, pc)
  170. Panel    *p;
  171. char    *name;
  172. {
  173. register int    len = strlen(name)+1;
  174. register PressButton    *pb;
  175. if (x<0 || x + len > p->width || y<0 || y + ButtonHeight > p->height)
  176.     prgmerr(len, "PButton %s not fit in panel", name);
  177. pb = zalloc(sizeof(*pb), 1, name);
  178. pb->x = x;
  179. pb->y = y;
  180. pb->hei = ButtonHeight;
  181. pb->len = len*p->font_w + TextLMargin;
  182. pb->name = str_save(name);
  183. pb->color.p = pc;    /* pressed color */
  184. pb->color.v = PB_Fill;
  185. pb->tcolor = black1;
  186. pb->pan = p;
  187. pb->valid = True;
  188. return    pb;
  189. }
  190.  
  191. #define    PmMg    2
  192.  
  193. PopMenu*
  194. CreatePopMenu(pan, parent, name, menu, num)
  195. Panel    *pan;
  196. WinAttribute*    parent;
  197. char    *name, *menu[];
  198. {
  199. register int    i, w=0, sl;
  200. register PopMenu*    pm = zalloc(sizeof(*pm), 1, name);
  201.  
  202. pm->items = i = num;
  203. while (i--)
  204.     if ((sl=strlen(menu[i])) > w)    w = sl;
  205. if ((sl=strlen(name)+4) > w)    w = sl;
  206. pm->name = str_save(name);
  207. pm->dpy = pan->dpy;
  208. pm->x0 = pan->x0;
  209. pm->y0 = pan->y0 + pan->height + 8;
  210. PopLineHeight = 15 + PmMg;
  211. pm->w = w * 9 + TextLMargin;
  212. pm->h = num * PopLineHeight;
  213. pm->bgcolor = White;
  214. pm->fgcolor = Black;
  215. CreateWindow(pm, parent, 0, PointerMotionMask | ButtonAction, True, 0);
  216. XSetWindowBackground(parent->dpy, pm->win, pm->bgcolor);
  217. SetFontGetSize(pm, "9x15");
  218. pm->menu = menu;
  219. return    pm;
  220. }
  221.  
  222. #ifdef    __STDC__
  223. #define    PrepColor(c)    XSetForeground(pm->dpy, pm->gc, pm->##c##gcolor);
  224. #else
  225. #define    PrepColor(c)    XSetForeground(pm->dpy, pm->gc, pm->/**/c/**/gcolor);
  226. #endif
  227. #define    FillItem(i)    XFillRectangle(pm->dpy, pm->win, pm->gc,\
  228.                 0, (i)*PopLineHeight, pm->w, PopLineHeight);
  229. #define    WriteItem(i)    {    register char*    p=pm->menu[i];    \
  230.     XDrawString(pm->dpy, pm->win, pm->gc,    \
  231.         PmMg, (i)*PopLineHeight+pm->font_h, p, strlen(p));    }
  232. #define    DrawItem(i, g)    {    FillItem(i);    PrepColor(g);    WriteItem(i); }
  233.  
  234. PopingMenu(pm, n_th, expos, imgp, ni)    /* place cursor on n_th item */
  235. PopMenu    *pm;
  236. void    (*expos)();
  237. Image    **imgp;
  238. {
  239. Window    rw;
  240. int    cx, cy, bw, dp;
  241. XEvent    event;
  242. register int    i;
  243.  
  244. pm->interface = (VType*)&event;
  245. TopWindow(pm,True);
  246. XGetGeometry(pm->dpy, pm->win, &rw, &pm->x0, &pm->y0, &cx, &cy, &bw, &dp);
  247. while(!XCheckMaskEvent(pm->dpy, ButtonAction, &event));
  248. XWarpPointer(pm->dpy, event.xbutton.window, pm->win, 0, 0, 0, 0,
  249.     pm->w>>1, --n_th * PopLineHeight);
  250. PrepColor(b);
  251. XFillRectangle(pm->dpy, pm->win, pm->gc, 0, 0, pm->w, pm->h);
  252. PrepColor(f);
  253. for (i=pm->items; i--;)
  254.     WriteItem(i);
  255.  
  256. while(!XCheckMaskEvent(pm->dpy, ButtonReleaseMask, &event)){
  257.     if (XCheckMaskEvent(pm->dpy, PointerMotionMask, &event)){
  258.     cx = event.xmotion.x;
  259.     cy = event.xmotion.y;
  260.     pm->which = cy / (pm->font_h+PmMg) + 1;
  261.     if (cx>0 && cx<pm->w && cy>0 && cy<pm->h && i != pm->which){
  262.         if (i-- > 0)
  263.             DrawItem(i, f);
  264.         i = pm->which;
  265.         DrawItem(i-1, b);
  266.     }
  267.     }
  268.     if (expos && XCheckMaskEvent(pm->dpy, ExposureMask, &event))    {
  269.     register Image*    ip=NULL;
  270.     register int    in;
  271.     if (imgp && (in=WhichImage(event.xany.window, imgp, ni))>=0)
  272.         ip = imgp[in];
  273.     expos(&event, ip);
  274.     }
  275. }
  276. while(!XCheckMaskEvent(pm->dpy, ButtonAction, &event));
  277. HidingPopMenu(pm);
  278. pm->which=0;
  279. return    i;
  280. }
  281. #undef    PmMg
  282. #undef    PrepColor
  283. #undef    FillItem
  284. #undef    WriteItem
  285. #undef    DrawItem
  286.  
  287. /*=======================================================
  288. %    Following routines are to control panel parts    %
  289. =======================================================*/
  290. DrawButton(b)
  291. register Button    *b;
  292. {
  293. register int    i, p=0;
  294. if (b->valid)
  295.     for (i=0; i<b->numb; i++) {
  296.  
  297.     XSetForeground(b->pan->dpy, b->pan->gc,
  298.         i==ButtonState(b) ? b->dimcolor : b->color[i]);
  299.     XFillRectangle(b->pan->dpy, b->pan->win, b->pan->gc, b->x+p, b->y,
  300.         b->bw[i]-2, b->hei);
  301.     XSetForeground(b->pan->dpy, b->pan->gc,
  302.         i==ButtonState(b) ? Black : b->tcolor);
  303.     XDrawString(b->pan->dpy, b->pan->win, b->pan->gc, b->x + p + TextLMargin,
  304.         b->y + TextVMargin, b->bname[i], strlen(b->bname[i]));
  305.     p += b->bw[i];
  306.     }
  307. else
  308.     for (i=0; i<b->numb; i++) {
  309.     
  310.     XSetForeground(b->pan->dpy, b->pan->gc,
  311.         i==ButtonState(b) ? b->color[i] : b->dimcolor);
  312.     XDrawRectangle(b->pan->dpy, b->pan->win, b->pan->gc, b->x+p, b->y,
  313.         b->bw[i]-2, b->hei);
  314.     XSetForeground(b->pan->dpy, b->pan->gc, darkGray); /* buttom title */
  315.     XDrawString(b->pan->dpy, b->pan->win, b->pan->gc, b->x + p + TextLMargin,
  316.         b->y + TextVMargin, b->bname[i], strlen(b->bname[i]));
  317.     p += b->bw[i];
  318.     }
  319. XSetForeground(b->pan->dpy, b->pan->gc, white1); /* title name */
  320. XDrawString(b->pan->dpy, b->pan->win, b->pan->gc, b->namex, b->y + TextVMargin,
  321.     b->name, strlen(b->name));
  322. XFlush(b->pan->dpy);
  323. }
  324.  
  325. DrawPressButton(pb)
  326. register PressButton    *pb;
  327. {
  328. if (pb->valid) {
  329. XSetForeground(pb->pan->dpy, pb->pan->gc, pb->color.s[pb->state]);
  330. XFillArc(pb->pan->dpy, pb->pan->win, pb->pan->gc, pb->x, pb->y, pb->len, pb->hei,
  331.     0, 360<<6);
  332. XSetForeground(pb->pan->dpy, pb->pan->gc, Yellow);
  333. XDrawArc(pb->pan->dpy, pb->pan->win, pb->pan->gc,
  334.     pb->x, pb->y, pb->len, pb->hei, 0, 360<<6);
  335. }
  336. else    {
  337. XSetForeground(pb->pan->dpy, pb->pan->gc, Yellow);
  338. XDrawArc(pb->pan->dpy, pb->pan->win, pb->pan->gc,
  339.     pb->x, pb->y, pb->len, pb->hei, 0, 360<<6);
  340. }
  341. XSetForeground(pb->pan->dpy, pb->pan->gc, pb->tcolor);
  342. XDrawString(pb->pan->dpy, pb->pan->win, pb->pan->gc,
  343.     pb->x + TextLMargin, pb->y + TextVMargin, pb->name, strlen(pb->name));
  344. XFlush(pb->pan->dpy);
  345. }
  346.  
  347.  
  348. DrawSlider(s)
  349. register Slider    *s;
  350. {
  351. register int    i = s->rl+s->rx-s->namex+TextLMargin;
  352. char    value[32];
  353.  
  354. if (!s->valid)    return;
  355. if (s->numb>1)    i += s->rx - s->namex;
  356. XClearArea(s->pan->dpy, s->pan->win, s->namex, s->ry-s->pan->font_h-RailWidth,
  357.     i, s->sh+TextVMargin, 0);
  358. XSetForeground(s->pan->dpy, s->pan->gc, s->rcolor); /* draw rail */
  359. XFillRectangle(s->pan->dpy, s->pan->win, s->pan->gc, s->rx, s->ry, s->rl+s->sw,
  360.     RailWidth);
  361. for (i=0; i<s->numb; i++){
  362.     XSetForeground(s->pan->dpy, s->pan->gc, s->scolor[i]);
  363.     XFillRectangle(s->pan->dpy, s->pan->win, s->pan->gc, s->sx[i], s->sy[i],
  364.         s->sw, s->sh);
  365. }
  366. XSetForeground(s->pan->dpy, s->pan->gc, s->tcolor);/* write name */
  367. XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->namex,
  368.     s->ry+s->pan->font_h, s->name, strlen(s->name));
  369. XDrawLine(s->pan->dpy, s->pan->win, s->pan->gc, s->namex, s->ry, s->rx-2, s->ry);
  370. sprintf(value, "%d", ReadSlider(s, 1));
  371. XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->namex,
  372.     s->ry-(s->pan->font_h>>1), value, strlen(value));
  373.  
  374. if (s->numb>1) {    /* on the top of another number
  375.     XSetForeground(s->pan->dpy, s->pan->gc, s->scolor[1]);
  376.     XDrawLine(s->pan->dpy, s->pan->win, s->pan->gc,
  377.         s->namex, s->ry-s->pan->font_h-RailWidth,
  378.         s->rx-2, s->ry-s->pan->font_h-RailWidth);
  379.     sprintf(value, "%d", ReadSlider(s, 2));
  380.     XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->namex,
  381.         s->ry-s->pan->font_h - TextVMargin, value, strlen(value));
  382. }
  383. */    XSetForeground(s->pan->dpy, s->pan->gc, white1);
  384.     sprintf(value, "%d", ReadSlider(s, 2));
  385.     i = strlen(value);
  386.     XDrawLine(s->pan->dpy, s->pan->win, s->pan->gc, s->rx+s->rl+s->sw+4,
  387.         s->ry, s->rx+s->rl+s->sh+i*s->pan->font_w, s->ry);
  388.     XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->rx+s->rl+s->sw+4,
  389.         s->ry-(s->pan->font_h>>1), value, i);
  390. }
  391. SliderInfo(s, Gray);
  392. }
  393.  
  394. SliderInfo(s, color)
  395. register Slider    *s;
  396. {
  397. char    value[32];
  398. register int    slen = strlen(s->info);
  399. XSetForeground(s->pan->dpy, s->pan->gc, color);
  400. if (slen)
  401.     XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->infx,
  402.     s->infy, s->info, slen);
  403. sprintf(value, "%d", s->min);
  404. slen = strlen(value);
  405. XDrawString(s->pan->dpy, s->pan->win, s->pan->gc, s->rx,
  406.     s->infy, value, slen);
  407. sprintf(value, "%d", s->max);
  408. slen = strlen(value);
  409. XDrawString(s->pan->dpy, s->pan->win, s->pan->gc,
  410.     s->rx + s->rl - s->pan->font_w*slen, s->infy, value, slen);
  411. XFlush(s->pan->dpy);
  412. }
  413.  
  414. ChangeSliderScale(s, scale, active)/* scale=0 reset scale to default */
  415. register Slider    *s;
  416. {
  417. s->scale = scale ? scale : s->defscale;
  418. s->min = s->defmin * s->scale;
  419. s->max = s->defmax * s->scale;
  420. if (active){
  421.     EraseSlider(s);
  422.     DrawSlider(s);
  423. }
  424. }
  425.  
  426. /*    set Slider Bar in value (p) postion.    */
  427. SetSBarRPos(s, p, bar)
  428. register Slider    *s;
  429. {
  430. if (bar > s->numb || p < s->min || p > s->max)    return    0;
  431. p -= s->min;
  432. if (s->vert)
  433.     return    s->sy[bar-1] = p / s->scale + s->ry;
  434. else    return    s->sx[bar-1] = p / s->scale + s->rx;
  435. }
  436.  
  437. /*    set Slider Bar postion by point on panel    */
  438. SetSBarPos(s, x, y, bar)
  439. register Slider    *s;
  440. {
  441. if (bar > s->numb)    return    0;
  442. if (!s->vert)
  443.     if (x < s->rx || x > s->rx+s->rl)    return    0;
  444.     else    s->sx[bar-1] = x;
  445. else if (y < s->ry || y > s->ry+s->rl)    return    0;
  446.     else    s->sy[bar-1] = y;
  447. #ifdef    _DEBUG_
  448. if (DEBUGANY){
  449.     message("SB(%d): rx=%d, ry=%d, sx1=%d, sy1=%d", bar,
  450.         s->rx, s->ry, s->sx[0], s->sy[0]);
  451.     if (s->numb>1)
  452.         message(" sx2=%d, sy2=%d",s->sx[1], s->sy[1]);
  453.     mesg("\n");
  454. }
  455. #endif
  456. DrawSlider(s);
  457. return    1;
  458. }
  459.  
  460. /* return Bar ID (number=1, 2,...); 0 is nothing on a Bar    */
  461. OnSliderBar(s, xbutton)
  462. register Slider    *s;
  463. XButtonEvent    *xbutton;
  464. {
  465. register int    i, x=xbutton->x, y=xbutton->y;
  466. if (!s->valid || xbutton->window != s->pan->win)    return    0;
  467. if (s->vert){    /* vert    */
  468.     if (x < s->sx[0] || x > s->sx[s->numb-1] + s->sw)    return    0;
  469.     for (i=0; i<s->numb; i++)
  470.         if (y >= s->sy[i] && y < s->sy[i] + s->sh)    return    i+1;
  471. }
  472. else    {
  473.     if (y < s->sy[0] || y > s->sy[s->numb-1] + s->sh)    return    0;
  474.     for (i=0; i<s->numb; i++)
  475.         if (x >= s->sx[i] && x < s->sx[i] + s->sw)    return    i+1;
  476. }
  477. return    0;
  478. }
  479.  
  480. OnButton(b, xbutton)
  481. register Button    *b;
  482. XButtonEvent    *xbutton;
  483. {
  484. register int    i, w, x=xbutton->x, y=xbutton->y;
  485.  
  486. if (xbutton->window != b->pan->win || !b->valid)    return    False;
  487.  
  488. #ifdef    _DEBUG_
  489. DEBUGMESSAGE("OnB: x=%d, y=%d, bx=%d, by=%d, rmb=%d\n", x,y,b->x,b->y,b->rmb);
  490. #endif
  491. x -= b->x;
  492. if (y < b->y || y > b->y + b->hei || x < 0 || x > b->rmb)
  493.     return    -1;
  494. for (i=w=0; i<b->numb; i++){
  495.     w += b->bw[i];
  496.     if (x < w)
  497.         if (i == ButtonState(b))    return    0;
  498.         else{
  499.         ButtonState(b) = i++;
  500.         DrawButton(b);
  501.         return    i;
  502.         }
  503. }
  504. }
  505.  
  506. bool
  507. ButtonPressed(pb, xbutton)
  508. PressButton    *pb;
  509. XButtonEvent    *xbutton;
  510. {
  511. register bool    state;
  512. register int    x=xbutton->x, y=xbutton->y;
  513. if (!pb->valid || pb->state || xbutton->window != pb->pan->win)
  514.     return    False;
  515. state = (x>=pb->x && x<pb->x+pb->len && y>=pb->y && y<pb->y+pb->hei);
  516. if (state){
  517.     PressButtonState(pb) = state;
  518.     DrawPressButton(pb);
  519. }
  520. return    state;
  521. }
  522.  
  523. void
  524. ResetPressButton(pb)
  525. register PressButton    *pb;
  526. {
  527. PressButtonState(pb) = RESETSTATE;
  528. DrawPressButton(pb);
  529. }
  530.  
  531.  
  532. ReadSlider(s, h)
  533. register Slider    *s;
  534. {
  535. register int    tmp;
  536. register float    scale = ((float)s->max - s->min) / s->rl;
  537. if (h<1 || h>s->numb)    h = s->numb;
  538. h--;
  539. if (s->vert)
  540.     tmp = s->sy[h];
  541. else    tmp = s->sx[h];
  542. return    (tmp - s->rx) * scale + s->min;
  543. }
  544.  
  545. /*=======================================================
  546. %    return currently pressed button name(label)    %
  547. %    It may be defined as a macro define        %
  548. =======================================================*/
  549. char*
  550. ReadButton(b)
  551. Button    *b;
  552. {
  553. return    b->bname[ButtonState(b)];
  554. }
  555.  
  556. void
  557. EraseSlider(s)
  558. register Slider    *s;
  559. {
  560. if (s->vert)
  561.     XClearArea(s->pan->dpy, s->pan->win, s->namex - TextLMargin, 0,
  562.     (TextLMargin<<1) + s->rl + s->rx - s->namex + s->sw, 0, 0);
  563. else    /*    correct    */
  564.     XClearArea(s->pan->dpy, s->pan->win, 0, s->infy-TextVMargin,
  565.     0, s->sy[0] - s->infy + (TextVMargin<<1) + s->sh, 0);
  566. }
  567.  
  568. /*===============================================
  569. %    A text line editor for panel input    %
  570. %    if x0 = 0, use right side area of b    %
  571. %    else use information area of panel    %
  572. ===============================================*/
  573. TextLine(b, buf, len, x0, exp_hd, imgp, imgs)
  574. Button    *b;
  575. char    *buf;
  576. int    len, x0, (*exp_hd)(), imgs;
  577. Image    *imgp;    /* for exposure handle    */
  578. {
  579. int    bufl=strlen(buf), chars_line, max_field, /* maximum text filed */
  580.     cursor_p, sl, ys, y0; /* top of the text line */
  581. char    str[16];
  582. bool    nodone=1, new=bufl;
  583.  
  584. if (!x0){
  585.     x0 = b->x + b->rmb;
  586.     y0 = b->y;
  587. }
  588. else    y0 = b->pan->height - (b->pan->font_h-1<<1);
  589.  
  590. ys = y0 + (b->hei>>1);    /* string height */
  591.  
  592. chars_line = (b->pan->width - x0) / b->pan->font_w - 1;
  593. max_field = MIN(len*b->pan->font_w, b->pan->width - x0);
  594. XClearArea(b->pan->dpy, b->pan->win, x0, y0, max_field, b->hei, 0);
  595. XSetForeground(b->pan->dpy, b->pan->gc, white1);
  596. XDrawLine(b->pan->dpy, b->pan->win, b->pan->gc, x0, y0+b->hei,
  597.     x0+max_field, y0+b->hei);
  598. cursor_p = MIN(bufl, chars_line);
  599. if (cursor_p)
  600.     XDrawString(b->pan->dpy, b->pan->win, b->pan->gc, x0, ys,
  601.     buf + (bufl<chars_line ? 0 : bufl-cursor_p), cursor_p);
  602. XBell(b->pan->dpy, 0);    /* beep to start input */
  603.  
  604. do    {
  605. XComposeStatus    status;
  606. KeySym    keysym;
  607.     FlushingCursor(b->pan,    exp_hd, imgp, imgs, x0 + cursor_p*b->pan->font_w,
  608.         y0, b->pan->font_w, b->pan->font_h, 15, 0);
  609.     sl = XLookupString(&b->pan->event, str, 16, &keysym, &status);
  610.  
  611.     str[sl] = 0; /* set end of string */
  612.     if (str[0] == BS | *str == 0x7F){    /* ctrl-H or DEL */
  613.         if (!bufl)    continue;
  614.         if (bufl-- <= chars_line){
  615.             XClearArea(b->pan->dpy, b->pan->win,
  616.             x0+cursor_p*b->pan->font_w, y0, b->pan->font_w, b->hei, 0);
  617.             cursor_p = bufl;
  618.         }
  619.         else    {
  620.             XClearArea(b->pan->dpy, b->pan->win, x0, y0, max_field, b->hei, 0);
  621.             XDrawString(b->pan->dpy, b->pan->win, b->pan->gc, x0, ys,
  622.             buf + bufl-cursor_p, cursor_p);
  623.         }
  624.         buf[bufl] = new = 0;
  625.     }
  626.     else if (str[0] == Esc)    return    0;    /* Undo */
  627.     else if (str[0] == Tab){    /* Cat. So set new to False */
  628.         new = 0;    continue;
  629.     }
  630.     else if (nodone = str[0] - '\r'){
  631.         if (new){    /* clear all to start a new line */
  632.         XClearArea(b->pan->dpy, b->pan->win, x0,y0,max_field,b->hei,0);
  633.         XSetForeground(b->pan->dpy, b->pan->gc, white1);
  634.         XDrawLine(b->pan->dpy, b->pan->win, b->pan->gc, x0, y0+b->hei,
  635.             x0+max_field, y0+b->hei);
  636.         buf[0] = new = cursor_p = bufl = 0;
  637.         }
  638.         strcat(buf, str);
  639.         bufl += sl;
  640.         if (bufl <= chars_line){
  641.         XDrawString(b->pan->dpy, b->pan->win, b->pan->gc,
  642.             x0+cursor_p*b->pan->font_w, ys, str, sl);
  643.         cursor_p = bufl;    /* set cursor position */
  644.         }
  645.         else{
  646.         XClearArea(b->pan->dpy, b->pan->win, x0, y0, max_field, b->hei, 0);
  647.         XDrawString(b->pan->dpy, b->pan->win, b->pan->gc,
  648.             x0, ys, buf + bufl-cursor_p, cursor_p);
  649.         }
  650.     }
  651. }while (nodone && strlen(buf)<len);
  652. return    strlen(buf);
  653. }
  654.  
  655. /*=======================================================
  656. %    display message at bottom area of the panel    %
  657. =======================================================*/
  658. DispInfo(p, xoffset, str, color)
  659. Panel    *p;
  660. char    *str;
  661. {
  662. XClearArea(p->dpy, p->win, xoffset, p->height-(p->font_h<<1),
  663.     p->width-xoffset, p->font_h<<1, 0);
  664. XSetForeground(p->dpy, p->gc, color);
  665. XDrawString(p->dpy, p->win, p->gc, xoffset+p->font_w, p->height-p->font_h,
  666.     str, strlen(str));
  667. XFlush(p->dpy);
  668. }
  669.  
  670. /*=======================================================
  671. %    display message onto right area of panel parts    %
  672. %    or onto given place. If any of x0, y0 and len    %
  673. %    is zero, then it will be set to parts->x,    %
  674. %    parts->y and length of the right area of parts    %
  675. =======================================================*/
  676. PanelMessage(pp, pmsg, x0, y0, len)
  677. AnyParts*    pp;
  678. char    *pmsg;
  679. register int    x0, y0, len;
  680. {
  681. if (!x0)    x0 = pp->x+pp->w;
  682. if (!y0)    y0 = pp->y-1;
  683. if (!len)    len = pp->pan->width - pp->x - pp->pan->font_w;
  684. XClearArea(pp->pan->dpy, pp->pan->win, x0, y0, len, pp->pan->font_h+2, 0);
  685. XSetForeground(pp->pan->dpy, pp->pan->gc, pp->vcolor);
  686. XDrawString(pp->pan->dpy, pp->pan->win, pp->pan->gc,
  687.     x0, y0+pp->pan->font_h, pmsg, strlen(pmsg));
  688. XFlush(pp->pan->dpy);
  689. }
  690.